package hos.soap;

import org.jetbrains.annotations.NotNull;
import org.ksoap2.serialization.SoapSerializationEnvelope;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

import hos.http.HttpBaseRequestSoap;
import hos.http.HttpCall;
import hos.http.HttpCallback;
import hos.http.HttpRequest;
import hos.okhttp.utils.OkHttpUtils;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * <p>Title: SoapFactory </p>
 * <p>Description:  </p>
 * <p>Company: www.mapuni.com </p>
 *
 * @author : 蔡俊峰
 * @version : 1.0
 * @date : 2023/3/3 17:58
 */
@SuppressWarnings("unchecked")
public class SoapFactory implements HttpCall.Factory {

    private final OkHttpClient okHttpClient;

    public SoapFactory() {
        okHttpClient = initOkHttp(new OkHttpClient.Builder())
                .connectTimeout(120, TimeUnit.SECONDS)
                .readTimeout(120, TimeUnit.SECONDS)
                .writeTimeout(120, TimeUnit.SECONDS)
                .retryOnConnectionFailure(false)
                .build();
    }

    public SoapFactory(OkHttpClient okHttpClient) {
        this.okHttpClient = okHttpClient;
    }

    protected OkHttpClient.Builder initOkHttp(OkHttpClient.Builder builder) {
        return builder;
    }

    @Override
    public <T> HttpCall<T> newCall(HttpRequest<?> request) {
        // 这里直接使用ksoap2-android封装，废弃
//        if (request instanceof HttpRequestSoap) {
//            return newSoap((HttpRequestSoap) request);
//        }
        // 直接封装使用OkHttp最新版本。
        SoapSerializationEnvelope envelope = null;
        if (request instanceof HttpBaseRequestSoap<?>) {
            envelope = SoapUtils.buildSoapSerializationEnvelope((HttpBaseRequestSoap<?>) request);
        }
        String url = request.getQueryUrl();
        // 获取请求 OkHttpClient
        OkHttpClient client = SoapUtils.buildOkhttp(okHttpClient, request);
        // 请求头部处理
        Headers.Builder headers = OkHttpUtils.buildRequestHeader(request);
        // 处理请求体
        RequestBody requestBody = SoapUtils.buildRequestBody(request, envelope);
        // 创建请求
        Request.Builder requestReal = OkHttpUtils.buildRequest(request, url, headers.build(), requestBody);
        // 添加Tag 在过滤器 OkHttpSoapInterceptor 中进行解析XML
        if (request instanceof HttpBaseRequestSoap<?>) {
            requestReal.tag(SoapSerializationEnvelope.class, envelope);
        }
        Call call = client.newCall(requestReal.build());
        return buildHttpCall(request, call);
    }

    /**
     * 这里直接使用ksoap2-android封装，废弃
     * @param request 请求体
     */
//    private <T> HttpCall<T> newSoap(HttpRequestSoap request) {
//        String url = request.getUrl();
//        HttpConfig config = Http.config();
//        String soapAction = request.getSoapAction();
//        List<HeaderProperty> headerList = SoapUtils.buildHeader(request);
//        final SoapSerializationEnvelope envelope = SoapUtils.buildSoapSerializationEnvelope(request);
//        // 获取请求 OkHttpClient
//        OkHttpClient client = buildOkhttp(request);
//        final OkHttpTransportSE transport = new OkHttpTransportSE(client, null, url, request.getConnectTimeout(), 0);
//        transport.debug = config.isDebug();
//        return new HttpCall<T>() {
//            @Override
//            public T execute() throws IOException {
//                try {
//                    transport.call(soapAction, envelope, headerList); // 调用webservice
//                    String result = envelope.getResponse().toString();
//                    if (Http.config().isDebug()) {
//                        Log.w("Http", result);
//                    }
//                    return (T) result;
//                } catch (SoapFault e) {
//                    throw HttpException.throwFailure(request.getQueryUrl(), request.getBodyParameters(), e);
//                } catch (HttpResponseException e) {
//                    throw HttpException.throwResponse(request.getQueryUrl(), request.getBodyParameters(), e);
//                } catch (XmlPullParserException e) {
//                    throw HttpException.throwConverter(request.getQueryUrl(), request.getBodyParameters(), e);
//                } catch (Exception e) {
//                    throw HttpException.throwFailure(request.getQueryUrl(), request.getBodyParameters(), e);
//                }
//            }
//
//            @Override
//            public void enqueue(HttpCallback<T> callback) {
//                if (HttpConfig.isMainThread()) {
//                    HttpConfig.runIo(() -> enqueue(callback));
//                    return;
//                }
//                try {
//                    transport.call(soapAction, envelope, headerList); // 调用webservice
//                    String result = envelope.getResponse().toString();
//                    if (Http.config().isDebug()) {
//                        Log.w("Http", result);
//                    }
//                    callback.onSuccess(request, (T) result);
//                } catch (SoapFault e) {
//                    callback.onFailed(HttpException.throwFailure(request.getQueryUrl(), request.getBodyParameters(), e));
//                } catch (HttpResponseException e) {
//                    callback.onFailed(HttpException.throwResponse(request.getQueryUrl(), request.getBodyParameters(), e));
//                } catch (XmlPullParserException e) {
//                    callback.onFailed(HttpException.throwConverter(request.getQueryUrl(), request.getBodyParameters(), e));
//                } catch (Exception e) {
//                    callback.onFailed(HttpException.throwFailure(request.getQueryUrl(), request.getBodyParameters(), e));
//                }
//            }
//        };
//    }

    /**
     * 创建请求
     */
    protected <T> HttpCall<T> buildHttpCall(HttpRequest<?> request, Call call) {
        return new HttpCall<T>() {
            @Override
            public T execute() throws IOException {
                return (T) call.execute();
            }

            @Override
            public void enqueue(HttpCallback<T> callback) {
                SoapFactory.this.<T>enqueue(request, call, callback);
            }
        };
    }

    /**
     * 异步请求
     */
    protected <T> void enqueue(HttpRequest<?> request, Call call, HttpCallback<T> callback) {
        call.enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                if (callback != null) {
                    callback.onFailed(e);
                }
            }

            @SuppressWarnings("unchecked")
            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                if (callback != null) {
                    callback.onSuccess(request, (T) response);
                }
            }
        });
    }

}
